using System;
using System.Collections.Generic;
using UnityEngine;

namespace CornerMemo
{
    public class EventCenter
    {
        private static EventCenter _eventInstance;
        private static EventCenter Instance
        {
            get
            {
                _eventInstance = _eventInstance ?? new EventCenter();
                return _eventInstance;
            }
        }
    
        private Dictionary<int, EventHandler> _handlerDic = new Dictionary<int, EventHandler>();
        /// <summary>
        /// 订阅事件。
        /// </summary>
        public static void Subscribe(int eventId, EventHandler handler) => Instance.m_Subscribe(eventId, handler);
        /// <summary>
        /// 不重复订阅事件。
        /// </summary>
        public static void SubscribeUnique(int eventId, EventHandler handler) => Instance.m_SubscribeUnique(eventId, handler);
        /// <summary>
        /// 取消订阅事件。
        /// </summary>
        public static void Unsubscribe(int eventId, EventHandler handler) => Instance.m_Unsubscribe(eventId, handler);
    
        /// <summary>
        /// 判断是否订阅过事件。
        /// </summary>
        public static bool HasSubscribe(int eventId) => Instance.m_HasSubscribe(eventId);
        
        /// <summary>
        /// 触发事件。
        /// </summary>
        public static void Fire(object sender, GameEventArgs e) => Instance.m_Fire(sender, e);
        
        private void m_Subscribe(int eventId, EventHandler handler)
        {
            //$"订阅事件 id：{eventId} handler：{handler.Method.Name}".InfoColor(Color.yellow);
            if (_handlerDic.ContainsKey(eventId))
            {
                _handlerDic[eventId] += handler;
            }
            else
            {
                _handlerDic.Add(eventId, handler);
            }
        }

        private void m_SubscribeUnique(int eventId, EventHandler handler)
        {
            if (_handlerDic.ContainsKey(eventId))
            {
                _handlerDic[eventId] -= handler;
                _handlerDic[eventId] += handler;
            }
            else
            {
                _handlerDic.Add(eventId, handler);
            }
        }
        
        private void m_Unsubscribe(int eventId, EventHandler handler)
        {
            //$"取消订阅事件 id：{eventId} handler：{handler.Method.Name}".InfoColor(Color.yellow);
            if (_handlerDic.ContainsKey(eventId))
            {
                _handlerDic[eventId] -= handler;
            }
            else
            {
                throw new ArgumentException("EventId not found.");
            }
        }

        public bool m_HasSubscribe(int eventId)
        {
            return _handlerDic.ContainsKey(eventId);
        }
    
        private void m_Fire(object sender, GameEventArgs e)
        {
            //$"触发事件 id：{e.Id} args：{e.GetType().Name}".InfoColor(Color.yellow);
            if (_handlerDic.ContainsKey(e.Id) && _handlerDic[e.Id]!=null)
            {
                _handlerDic[e.Id](sender, e);
            }
        }
        
    }
}